<!-- 滚动组件 -->
<template>
  <view class="nav-box">
    <scroll-view
      scroll-x="true"
      @scroll="scroll"
      @touchmove.stop
      @scrolltoupper="scrolltoupperHandler"
      @scrolltolower="scrolltolowerHandler"
      class="scroll-view"
      bounces="true"
      show-scrollba="false"
      enhanced="true"
      scroll-anchoring="true"
      scroll-left="1"
    >
      <view
        :class="styleType == 1 ? 'navF' : 'navG'"
        :style="
          styleType == 2
            ? `grid-template-rows: repeat(${rows}, 1fr); grid-template-columns: repeat(5, 1fr);`
            : ''
        "
      >
        <slot></slot>
      </view>
    </scroll-view>
    <view class="scroll-box" v-show="(lL / rows > rows && styleType == 2) || isScroll">
      <view class="scroll" :style="'transform: translateX(' + sX + ')'" />
    </view>
  </view>
</template>

<script setup lang="ts">
  import { onMounted, ref, getCurrentInstance, reactive } from 'vue';

  // 获取组件实例
  const instance = getCurrentInstance();

  const props = defineProps({
    styleType: {
      type: Number,
      default: 2,
    },
    // 定义有几行,当styleType为2时有效
    rows: {
      type: Number,
      default: 2,
    },
    // 列表长度
    lL: {
      type: Number,
      default: 0,
    },
    // 是否显示滚动条
    isScroll: {
      type: Boolean,
      default: true,
    },
  });

  /**
   * 等比偏移量
   */
  const sX = ref<string>('0rpx');
  /**
   * 最外围容器宽度
   */
  const scrollWidth = ref<number>(0);
  /**
   * 滚动条盒子宽度
   */
  const indicatorWidth = ref<number>(0);
  /**
   * 滚动条中滚动块的宽度
   */
  const indicatorBarWidth = ref<number>(0);

  const scrollInfo = reactive({
    scrollLeft: 0,
    scrollWidth: 0,
  });

  const scroll = (e: any) => {
    scrollInfo.scrollLeft = e.detail.scrollLeft;
    scrollInfo.scrollWidth = e.detail.scrollWidth;

    const left = scrollInfo.scrollLeft;
    const width = scrollInfo.scrollWidth;
    const barwidth = indicatorWidth.value - indicatorBarWidth.value;
    const x = (left / (width - scrollWidth.value)) * barwidth;
    sX.value = x + 'px';
  };

  const scrolltoupperHandler = () => {
    scrollInfo.scrollLeft = 0;
  };
  const scrolltolowerHandler = () => {
    scrollInfo.scrollLeft = indicatorWidth.value - indicatorBarWidth.value;
  };

  onMounted(() => {
    // 初始化组件宽度
    getComponentWidth();
  });

  // 获取组件的宽度
  const getComponentWidth = () => {
    // 延时一定时间，以获取dom尺寸
    setTimeout(() => {
      const query = uni.createSelectorQuery().in(instance);
      query
        .selectAll('.nav-box,.scroll-box,.scroll')
        .boundingClientRect((data: any) => {
          // dome元素从外到内依次获取数据，所以写法按顺序来才不会混
          scrollWidth.value = data[0].width;
          indicatorWidth.value = data[1].width;
          indicatorBarWidth.value = data[2].width;
        })
        .exec();
    }, 30);
  };
</script>

<style>
  .nav-box {
    width: 100%;
    padding-left: 20rpx;
    padding-right: 20rpx;
  }

  .navG {
    display: grid;
    grid-auto-flow: column;
    grid-template-columns: repeat(auto-fill, 1fr);
  }

  .navF {
    display: flex;
    flex-wrap: nowrap;
  }

  .scroll-box {
    width: 50rpx;
    height: 6rpx;
    background: #d6d6d6;
    border-radius: 5rpx;
    margin: -6rpx auto 0rpx;
  }

  .scroll {
    width: 26rpx;
    height: 100%;
    background: #ff6d2a;
    border-radius: 5rpx;
  }

  .scroll-view {
    background-color: #fff;
    white-space: nowrap;
    border-radius: 20rpx;
  }
</style>
